package com.leadingsoft.pwxk.sync;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.leadingsoft.pwxk.commons.NamedThreadFactory;
import com.leadingsoft.pwxk.enums.InterfaceEnum;
import com.leadingsoft.pwxk.model.AirPermitInfo;
import com.leadingsoft.pwxk.model.AirPollution;
import com.leadingsoft.pwxk.model.AirPollutionNoOrg;
import com.leadingsoft.pwxk.model.AirPollutionOrg;
import com.leadingsoft.pwxk.model.AuditAirPollutionEmissions;
import com.leadingsoft.pwxk.model.AuditBaseInfo;
import com.leadingsoft.pwxk.model.AuditCert;
import com.leadingsoft.pwxk.model.AuditMessages;
import com.leadingsoft.pwxk.model.AuditPerformReport;
import com.leadingsoft.pwxk.model.AuditPublicInfo;
import com.leadingsoft.pwxk.model.AuditSelfMonitor;
import com.leadingsoft.pwxk.model.AuditWaterEmissions;
import com.leadingsoft.pwxk.model.BaseInfo;
import com.leadingsoft.pwxk.model.DrainMana;
import com.leadingsoft.pwxk.model.FacilityAppendix;
import com.leadingsoft.pwxk.model.FileDetail;
import com.leadingsoft.pwxk.model.LicenseInfo;
import com.leadingsoft.pwxk.model.ManaLocal;
import com.leadingsoft.pwxk.model.ManaRecordInfo;
import com.leadingsoft.pwxk.model.ManaSelf;
import com.leadingsoft.pwxk.model.OtherController;
import com.leadingsoft.pwxk.model.Pollutions;
import com.leadingsoft.pwxk.model.ProcessChart;
import com.leadingsoft.pwxk.model.Product;
import com.leadingsoft.pwxk.model.ProductMaterial;
import com.leadingsoft.pwxk.model.PwBaseInfo;
import com.leadingsoft.pwxk.model.RegionCode;
import com.leadingsoft.pwxk.model.Summary;
import com.leadingsoft.pwxk.model.TZRecord;
import com.leadingsoft.pwxk.model.UndoBaseInfo;
import com.leadingsoft.pwxk.model.WaterDrain;
import com.leadingsoft.pwxk.model.WaterDrainApply;
import com.leadingsoft.pwxk.services.AbstractService;
import com.leadingsoft.pwxk.services.LatestDataService;
import com.leadingsoft.pwxk.services.SummaryService;
import com.leadingsoft.pwxk.services.SyncRecordService;
import com.leadingsoft.pwxk.task.FetchDataTask;
import com.leadingsoft.pwxk.task.LatestDataTask;

@Component
public class SyncDataTask {
	@Autowired
	private AbstractService<BaseInfo> baseInfoService;
	@Autowired
	private AbstractService<PwBaseInfo> pwBaseInfoService;
	@Autowired
	private AbstractService<AirPollution> airPollutionService;
	@Autowired
	private AbstractService<AirPollutionOrg> airPollutionOrgService;
	@Autowired
	private AbstractService<AirPollutionNoOrg> airPollutionNoOrgService;
	@Autowired
	private AbstractService<AirPermitInfo> airPermitInfofoService;
	@Autowired
	private AbstractService<WaterDrain> waterDrainService;
	@Autowired
	private AbstractService<WaterDrainApply> waterDrainApplyService;
	@Autowired
	private AbstractService<ManaSelf> manaSelfService;
	@Autowired
	private AbstractService<ManaRecordInfo> manaRecordInfoService;
	@Autowired
	private AbstractService<ManaLocal> manaLocalService;
	@Autowired
	private AbstractService<Product> productService;
	@Autowired
	private AbstractService<ProductMaterial> productMaterialService;

	@Autowired
	private AbstractService<DrainMana> drainManaService;

	@Autowired
	AbstractService<RegionCode> regionCodeService;

	@Autowired
	AbstractService<Pollutions> pollutionsService;

	@Autowired
	AbstractService<AuditCert> auditCertService;

	@Autowired
	AbstractService<OtherController> otherControllerService;

	@Autowired
	AbstractService<AuditPublicInfo> auditPublicInfoService;

	@Autowired
	AbstractService<TZRecord> tZRecordService;

	@Autowired
	AbstractService<AuditBaseInfo> auditBaseInfoService;

	@Autowired
	AbstractService<FileDetail> fileDetailService;

	@Autowired
	AbstractService<LicenseInfo> licenseInfoService;

	@Autowired
	AbstractService<AuditPerformReport> auditPerformReportService;

	@Autowired
	AbstractService<AuditSelfMonitor> auditSelfMonitorService;

	@Autowired
	AbstractService<AuditWaterEmissions> auditWaterEmissionsService;

	@Autowired
	AbstractService<AuditAirPollutionEmissions> auditAirPollutionEmissionsService;

	@Autowired
	AbstractService<Summary> summaryService;

	@Autowired
	SyncRecordService syncRecordService;

	@Autowired
	AbstractService<FacilityAppendix> facilityAppendixService;

	@Autowired
	AbstractService<ProcessChart> processChartService;

	@Autowired
	AbstractService<UndoBaseInfo> undoBaseInfoService;

	@Autowired
	AbstractService<AuditMessages> auditMessagesService;

	@Autowired
	LatestDataService latestDataService;

	@Autowired
	SyncProperties syncProperties;

	Object lock = new Object();

	@Autowired
	SummaryService summarys;

	@SuppressWarnings("rawtypes")
	@Scheduled(cron = "#{syncProperties['cron']}")
	public void doafter() {
		CountDownLatch countDownLatch = new CountDownLatch(34);
		List<Runnable> taskList = new ArrayList<Runnable>();
		taskList.add(new FetchDataTask(summaryService, InterfaceEnum.EPS_Message, countDownLatch, syncRecordService,
				lock, false));
		taskList.add(new FetchDataTask<BaseInfo>(baseInfoService, InterfaceEnum.EPS_REGISTER, countDownLatch,
				syncRecordService, lock, false));
		taskList.add(new FetchDataTask<PwBaseInfo>(pwBaseInfoService, InterfaceEnum.EPS, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<Product>(productService, InterfaceEnum.PRODUCT_CAPACITY, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<ProductMaterial>(productMaterialService, InterfaceEnum.MATERIAL_FUEL_INFO,
				countDownLatch, syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<DrainMana>(drainManaService, InterfaceEnum.EPS_NODE_FAC, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<AirPollution>(airPollutionService, InterfaceEnum.AIR_EMISSIONS_INFO,
				countDownLatch, syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<AirPollutionOrg>(airPollutionOrgService, InterfaceEnum.AIR_ORG_EMISSIONS,
				countDownLatch, syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<AirPollutionNoOrg>(airPollutionNoOrgService, InterfaceEnum.AIR_OORG_EMISSIONS,
				countDownLatch, syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<AirPermitInfo>(airPermitInfofoService, InterfaceEnum.EPS_AIR_INFO,
				countDownLatch, syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<WaterDrain>(waterDrainService, InterfaceEnum.WATER_EMISSIONS, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<WaterDrainApply>(waterDrainApplyService, InterfaceEnum.WATER_APPLY,
				countDownLatch, syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<ManaSelf>(manaSelfService, InterfaceEnum.SELF_MONITOR, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<ManaRecordInfo>(manaRecordInfoService, InterfaceEnum.RECORD, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask<ManaLocal>(manaLocalService, InterfaceEnum.ADD, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask(fileDetailService, InterfaceEnum.FILE, countDownLatch, syncRecordService, lock,
				summarys));
		taskList.add(new FetchDataTask(fileDetailService, InterfaceEnum.COMPARISON_TABLE, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask(licenseInfoService, InterfaceEnum.LICENSE, countDownLatch, syncRecordService,
				lock, summarys));
		taskList.add(new FetchDataTask(auditBaseInfoService, InterfaceEnum.BASIC_AUDIT, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask(auditAirPollutionEmissionsService, InterfaceEnum.AIR_EMISSIONS_AUDIT,
				countDownLatch, syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask(auditWaterEmissionsService, InterfaceEnum.WATER_EMISSIONS_AUDIT, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask(auditSelfMonitorService, InterfaceEnum.SELF_MONITOR_AUDIT, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask(auditPerformReportService, InterfaceEnum.REPORT, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask(auditPublicInfoService, InterfaceEnum.PUBLIC, countDownLatch, syncRecordService,
				lock, summarys));
		taskList.add(new FetchDataTask(tZRecordService, InterfaceEnum.RECORD_AUDIT, countDownLatch, syncRecordService,
				lock, summarys));
		taskList.add(new FetchDataTask(otherControllerService, InterfaceEnum.OTH_CON_AUDIT, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask(auditCertService, InterfaceEnum.CERT_AUDIT, countDownLatch, syncRecordService,
				lock, summarys));
		taskList.add(new FetchDataTask(fileDetailService, InterfaceEnum.FILE_AUDIT, countDownLatch, syncRecordService,
				lock, summarys));
		taskList.add(new FetchDataTask(pollutionsService, InterfaceEnum.POLLUTIONS, countDownLatch, syncRecordService,
				lock, false));
		taskList.add(new FetchDataTask(regionCodeService, InterfaceEnum.REGION_CODE, countDownLatch, syncRecordService,
				lock, false));
		taskList.add(new FetchDataTask(facilityAppendixService, InterfaceEnum.SCSSFU_INFO, countDownLatch,
				syncRecordService, lock, summarys));
		taskList.add(new FetchDataTask(processChartService, InterfaceEnum.GYLCT, countDownLatch, syncRecordService,
				lock, summarys));
		taskList.add(new FetchDataTask(undoBaseInfoService, InterfaceEnum.UNDO_INFO, countDownLatch, syncRecordService,
				lock, false));
		taskList.add(new FetchDataTask(auditMessagesService, InterfaceEnum.AUDIT_INFO, countDownLatch,
				syncRecordService, lock, summarys));
		// 跑完34个拉去接口数据任务之后，将最新企业dataid重新存入表中。
		taskList.add(new LatestDataTask(latestDataService, countDownLatch));
		ExecutorService executorService = Executors.newFixedThreadPool(10, new NamedThreadFactory());
		taskList.forEach(executorService::execute);
		// 1.终止前允许执行以前提交的任务。2.线程任务异常不影响后续线程执行。
		executorService.shutdown();
	}
}
